﻿using Prism.Ioc;
using Prism.Unity;
using Prism.Modularity;
using System.Windows;
using PrismMetroSample.Infrastructure.Services;
using PrismMetroSample.Infrastructure;
using PrismMetroSample.Shell.Views.Login;
using Prism.Regions;
using System.Windows.Controls.Primitives;
using PrismMetroSample.Infrastructure.CustomerRegionAdapters;
using PrismMetroSample.Shell.Views.Dialogs;
using PrismMetroSample.Shell.ViewModels.Dialogs;
using PrismMetroSample.Shell.Views;
using WPFGlobalExceptionHandling;
using System;
using PrismMetroSample.Shell.ViewModels;
using Unity;
using Unity.Interception;
using Unity.Interception.ContainerIntegration;
using Unity.Interception.Interceptors.InstanceInterceptors.InterfaceInterception;
using Unity.Interception.Interceptors.TypeInterceptors.VirtualMethodInterception;
using Unity.Lifetime;
using Unity.RegistrationByConvention;

namespace PrismMetroSample.Shell
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : PrismApplication, IWPFGlobalExceptionHandler
    {

        public App() : base()
        {
            this.UseGlobalExceptionHandling();
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
        }

        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //注册服务
            containerRegistry.Register<IMedicineSerivce, MedicineSerivce>();
            containerRegistry.Register<IPatientService, PatientService>();
            containerRegistry.Register<IUserService, UserService>();

            //注册全局命令
            containerRegistry.RegisterSingleton<IApplicationCommands, ApplicationCommands>();
            containerRegistry.RegisterInstance<IFlyoutService>(Container.Resolve<FlyoutService>());

            //注册导航
            containerRegistry.RegisterForNavigation<LoginMainContent>();
            containerRegistry.RegisterForNavigation<CreateAccount>();
            // Register Views
            containerRegistry.RegisterForNavigation<Views.ModuleAPopup>("ModuleAPopup");

            //注册对话框
            containerRegistry.RegisterDialog<AlertDialog, AlertDialogViewModel>();
            containerRegistry.RegisterDialog<SuccessDialog, SuccessDialogViewModel>();
            containerRegistry.RegisterDialog<WarningDialog, WarningDialogViewModel>();
            //containerRegistry.RegisterDialog<WindowTestView>();
            containerRegistry.RegisterForNavigation(typeof(WindowTestView), typeof(WindowTestView).Name);
            containerRegistry.RegisterDialogWindow<DialogWindow>();

            IUnityContainer container = containerRegistry.GetContainer();

            container.AddNewExtension<Interception>();

            var interceptor = container.Configure<Interception>();

            container.RegisterType(typeof(IDoWork)
                , typeof(DoWork)
                , null
                , new TransientLifetimeManager());

            interceptor.SetInterceptorFor(typeof(IDoWork), new InterfaceInterceptor());
            interceptor.SetInterceptorFor(typeof(MainWindowViewModel), new VirtualMethodInterceptor());
            interceptor.SetInterceptorFor(typeof(WindowTestViewModel), new VirtualMethodInterceptor());

            containerRegistry.GetContainer()
                .RegisterTypes(AllClasses.FromLoadedAssemblies(), WithMappings.FromAllInterfacesInSameAssembly,
                WithName.TypeName, WithLifetime.PerResolve);
            //AllClasses.FromAssemblies()
            //containerRegistry.GetContainer().AddNewExtension<Interception>().Configure<Interception>()
        }

        public static void RegisterTypes(IUnityContainer container)
        {
            container.RegisterTypes(
                AllClasses.FromLoadedAssemblies(),
                WithMappings.FromMatchingInterface,
                WithName.Default);
        }

        //protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        //{
        //    moduleCatalog.AddModule<PrismMetroSample.PatientModule.PatientModule>();
        //    var MedicineModuleType = typeof(PrismMetroSample.MedicineModule.MedicineModule);
        //    moduleCatalog.AddModule(new ModuleInfo()
        //    {
        //        ModuleName= MedicineModuleType.Name,
        //        ModuleType=MedicineModuleType.AssemblyQualifiedName,
        //        InitializationMode=InitializationMode.OnDemand
        //    });

        //}

        protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
        {
            base.ConfigureRegionAdapterMappings(regionAdapterMappings);
            regionAdapterMappings.RegisterMapping(typeof(UniformGrid), Container.Resolve<UniformGridRegionAdapter>());
        }

        protected override IModuleCatalog CreateModuleCatalog()
        {
            return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
            //return new ConfigurationModuleCatalog();
        }

        #region 添加全局异常捕获

        public void HandleException(Exception e)
        {
            // logs the exception, including inner exceptions
            //logger.Error(e);

            // shows a message box with the root exception
            MessageBox.Show(e.GetTheRootException().Message, "Uh-oh, something went wrong!", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        public void HandleUnrecoverableException(Exception e)
        {
            // logs the exception, including inner exceptions
            //logger.Fatal(e);

            // shows a message box with the root exception
            MessageBox.Show($"The application is now going to close.\n\n'{e.GetTheRootException().Message}'", "Unrecoverable Error!", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        #endregion

    }
}
